home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / prolog / modprolg / mod-prol.lha / Prolog / modlib / src / $assert.P < prev    next >
Encoding:
Text File  |  1992-05-21  |  13.2 KB  |  360 lines

  1. /************************************************************************
  2. *                                    *
  3. * The SB-Prolog System                            *
  4. * Copyright SUNY at Stony Brook, 1986; University of Arizona, 1987    *
  5. *                                    *
  6. ************************************************************************/
  7.  
  8. /*-----------------------------------------------------------------
  9. SB-Prolog is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY.  No author or distributor
  11. accepts responsibility to anyone for the consequences of using it
  12. or for whether it serves any particular purpose or works at all,
  13. unless he says so in writing.  Refer to the SB-Prolog General Public
  14. License for full details.
  15.  
  16. Everyone is granted permission to copy, modify and redistribute
  17. SB-Prolog, but only under the conditions described in the
  18. SB-Prolog General Public License.   A copy of this license is
  19. supposed to have been given to you along with SB-Prolog so you
  20. can know your rights and responsibilities.  It should be in a
  21. file named COPYING.  Among other things, the copyright notice
  22. and this notice must be preserved on all copies. 
  23. ------------------------------------------------------------------ */
  24.  
  25. /****************************************************************************
  26.  *                                                                          *
  27.  * This file has been changed by to include Modules Extensions              *
  28.  * Changes by : Brian Paxton 1991/92                                        *
  29.  * Last update : June 1992                                                  *
  30.  *                                                                          *
  31.  * Organisation : University of Edinburgh.                                  *
  32.  * For : Departments of Computer Science and Artificial Intelligence        * 
  33.  *       Fourth Year Project.                                               *
  34.  *                                                                          *
  35.  ****************************************************************************/
  36.  
  37. /* $assert.P */
  38.  
  39. $assert_export([$assert/1,$asserta/1,$asserta/2,$assertz/1,$assertz/2,
  40.         $assert/2,$asserti/2,$assert/4,$assert_union/2,
  41.         $assert_call_s/1,
  42.         $assert_get_prref/2,$assert_put_prref/2,$assert_abolish_i/1,
  43.         $assert/3,$asserta/3,$assertz/3,$asserti/3]).
  44.  
  45. % $assert_use : $meta, $blist, $buff, $modules, $db, $bio,
  46.  
  47. $assert_exp_cut((Head:-Body),(Nhead:-Nbody)) :- !,
  48.     $univ(Head,Hlist),$append(Hlist,[Cutpoint],Nhlist),
  49.     $univ(Nhead,Nhlist),
  50.     $assert_exp_cutb(Body,Nbody,Cutpoint).
  51.  
  52. $assert_exp_cut(Head,Head) .  /* leave unchanged, Arity is one less */
  53.  
  54. $assert_exp_cutb(X,call(X),_) :- var(X),!.
  55. $assert_exp_cutb(!,'_$cutto'(Cutpoint),Cutpoint) :- !.
  56. $assert_exp_cutb((X,Y), (call(X), call(Y)), _) :-
  57.     var(X), var(Y), !.
  58. $assert_exp_cutb((X,Y,Z), (call(X), call(Y), call(Z)), _) :-
  59.     var(X), var(Y), var(Z), !.
  60. $assert_exp_cutb((A,B,C,D),','(Na,Nb,Nc,Nd),Cutpoint) :- !, /* opt */
  61.     $assert_exp_cutb(A,Na,Cutpoint),
  62.     $assert_exp_cutb(B,Nb,Cutpoint),
  63.     $assert_exp_cutb(C,Nc,Cutpoint),
  64.     $assert_exp_cutb(D,Nd,Cutpoint).
  65. $assert_exp_cutb((A,B),(Na,Nb),Cutpoint) :- !,
  66.     $assert_exp_cutb(A,Na,Cutpoint),
  67.     $assert_exp_cutb(B,Nb,Cutpoint).
  68. $assert_exp_cutb((A;B),(Na;Nb),Cutpoint) :- !,
  69.     $assert_exp_cutb(A,Na,Cutpoint),
  70.     $assert_exp_cutb(B,Nb,Cutpoint).
  71. $assert_exp_cutb((A->B),(A->Nb),Cutpoint) :- !,
  72.     $assert_exp_cutb(B,Nb,Cutpoint).
  73. $assert_exp_cutb(X,X,_).
  74.  
  75. % Changes made here for modules and are self-explanatory.
  76.  
  77. $assert(Clause) :- 
  78.     $assert_get_index(Clause,Index),
  79.     $assert(Clause,1,Index,_,perv).
  80. $assert(Clause, Tag) :-
  81.     $isa_structuretag(Tag), !,
  82.     $assert_get_index(Clause,Index),
  83.     $assert(Clause,1,Index,_,Tag).
  84. $assert(Clause,Clref) :-
  85.     $assert_get_index(Clause,Index),
  86.     $assert(Clause,1,Index,Clref,perv).
  87. $assert(Clause,Clref,Tag) :-
  88.     ( $isa_structuretag(Tag)
  89.          -> $assert(Clause,1,Index,Clref,Tag) ;
  90.          ( $telling(X), $tell(user),
  91.            $writename('*** Error: Third argument to assert/3 must be a structure tag'),
  92.            $nl, $tell(X), fail ) ).
  93.  
  94. $asserta(Clause) :- 
  95.     $assert(Clause,0,0,Ref,perv).
  96. $asserta(Clause,Tag) :- 
  97.     $isa_structuretag(Tag), !,
  98.     $assert(Clause,0,0,_,Tag).
  99. $asserta(Clause,Ref) :- 
  100.     $assert(Clause,0,0,Ref,perv).
  101. $asserta(Clause,Ref,Tag) :-
  102.     ( $isa_structuretag(Tag)
  103.           -> $assert(Clause,0,0,Ref,Tag) ;
  104.          ( $telling(X), $tell(user),
  105.            $writename('*** Error: Third argument to asserta/3 must be a structure tag'),
  106.            $nl, $tell(X), fail ) ).
  107.  
  108. $assertz(Clause) :-
  109.         $assert_get_index(Clause,Index),
  110.         $assert(Clause,1,Index,_,perv).
  111. $assertz(Clause,Tag) :-
  112.     $isa_structuretag(Tag), !,
  113.         $assert_get_index(Clause,Index),
  114.     $assert(Clause,1,Index,_,Tag).
  115. $assertz(Clause,Ref) :-
  116.     $assert_get_index(Clause,Index),
  117.     $assert(Clause,1,Index,Ref,perv).
  118. $assertz(Clause,Ref,Tag) :-
  119.     ( $isa_structuretag(Tag)
  120.           -> ( $assert_get_index(Clause,Index),
  121.            $assert(Clause,1,Index,Ref,Tag) ) ;
  122.          ( $telling(X), $tell(user),
  123.            $writename('*** Error: Third argument to assertz/3 must be a structure tag'),
  124.            $nl, $tell(user), fail ) ).
  125.  
  126. $asserti(Clause,Index) :- 
  127.     $assert(Clause,1,Index,_,perv).
  128. $asserti(Clause,Index,Tag) :- 
  129.     ( $isa_structuretag(Tag)
  130.           -> $assert(Clause,1,Index,Ref,Tag) ;
  131.          ( $telling(X), $tell(user),
  132.            $writename('*** Error: Third argument to asserta/3 must be a structure tag'),
  133.            $nl, $tell(user), fail ) ).
  134.  
  135. $assert(Clause, AZ, Index, Clref) :- 
  136.     $assert(Clause, AZ, Index, Clref, perv).
  137.  
  138. % Main differences here are :
  139. % 1) You cannot assert something that has been declared as a function during
  140. %    a consult.
  141. % 2) If a remote structure is specified, the clause is moved to that
  142. %    structure before it is asserted. Clauses can only be moved if the tags
  143. %    they contain refer to the same structure.
  144.  
  145. $assert(Clause, AZ, Index, Clref, perv) :- !,
  146.     $check_not_function(Clause),
  147.         $assert_exp_cut(Clause,Nclause),
  148.         $assert_cvt_dyn(Clause,Prref,Where,Supbuff),
  149.         $db_assert_fact(Nclause,Prref,AZ,Index,Clref,Where,Supbuff),!.
  150.  
  151. $assert(Clause, AZ, Index, Clref, Tag) :- 
  152.     $check_destination(Clause,Oldtag),
  153.     $move_clause(Clause,Oldtag,Tag,Clause1),
  154.     $check_not_function(Clause1),
  155.     $fun_rel(Clause1,Clause2,Tag),
  156.     $assert_exp_cut(Clause2,Nclause),  
  157.     $assert_cvt_dyn(Clause2,Prref,Where,Supbuff),
  158.     $db_assert_fact(Nclause,Prref,AZ,Index,Clref,Where,Supbuff).
  159.  
  160. $assert_get_index(Clause,Index) :-
  161.      (Clause \= (_ :- _) ->
  162.           ($functor0(Clause,P), $arity(Clause,N)) ;
  163.           (arg(1,Clause,Hd), $functor0(Hd,P), $arity(Hd,N))
  164.      ),
  165.      (($symtype('_$index'(_,_,_),IType),
  166.        IType > 0,
  167.        '_$index'(P,N,Index)
  168.       ) ->
  169.            true ;
  170.            Index = 1
  171.      ).
  172.  
  173.  
  174. /* this is a translator for facts. It takes a term that represents 
  175.    a predicate call (a fact) and generates and writes the code 
  176.    corresponding to the fact into a buffer. It then asserts the fact 
  177.    by adding it to the end of the tryme-retryme-trustme sequence for
  178.    the main predicate of the fact.
  179. */
  180.  
  181.  
  182. /* $assert(Fact,AZ,Index,Clref):  asserts a fact to a fact-defined 
  183. predicate. Fact is the fact to assert. AZ is 0 for insertion as the
  184. first clause; 1 for insertion as the last clause. Index is the number of 
  185. the argument on which to index; 0 for no indexing. Clref is returned as
  186. the clause reference of the fact newly asserted. */
  187.  
  188.  
  189. $assert_cvt_dyn(Clause,Prref,Where,Supbuff) :-
  190.     (Clause = (Fact:-B),! ; Clause=Fact),
  191.     $symtype(Fact, SYMTYPE),
  192.     (SYMTYPE =:= 1 ->        /* already dynamic */
  193.       $assert_get_prref(Fact,Prref,Where,Supbuff)
  194.       ;
  195.       Where = 0,
  196.       (SYMTYPE =:= 0 ->        /* undefined, this is first clause */
  197.         $db_new_prref(Prref),
  198.         $assert_put_prref(Fact,Prref)
  199.         ;
  200.         (SYMTYPE =:= 2 ->        /* compiled, so convert */
  201.           $assert_cvt_buff(Fact,Ccls),
  202.           $db_new_prref(Prref),
  203.           $assert_put_prref(Fact,Prref),
  204.           $arity(Fact,Arity1),Arity is Arity1+1,
  205.           $db_add_clref(Fact,Arity,Prref,1,0,Ccls)
  206.           ;
  207.           ( $telling(X), $tell(user),
  208.         $writename('*** Error: cannot assert into Buffer'),
  209.         $nl, $tell(X), fail )
  210.         )
  211.       )
  212.     ).
  213.  
  214.  
  215. /* return a buffer with a branch to the clauses for Fact */
  216. $assert_cvt_buff(Fact,Tbuff) :-
  217.         $opcode( jump, JmpOp ),
  218.     $alloc_perm( 20,Tbuff),   /* buff to convert to dynamic */
  219.     $buff_code(Tbuff,  0, 14 /*ptv */ , Tbuff),    /* back ptr */
  220.     $buff_code(Tbuff, 12,  3 /*ps  */ , JmpOp /*jump*/ ),
  221.     $buff_code(Tbuff, 14,  3 /*ps  */ , 0),
  222.     $buff_code(Tbuff, 16, 20 /*pepb*/ , Fact).
  223.  
  224.  
  225. /* assert_union adds the clauses of the second predicate
  226.    to the first predicate. E.g., given p(X,Y) and q(X,Y), it adds the rule
  227.    p(X,Y) :- q(X,Y) as the last rule defining p. If p is not defined, then
  228.    it results in the call of q being the only clause for p */
  229.  
  230. % Note that you can no longer assert something that has been declared as a 
  231. % function during a consult.
  232.  
  233. $assert_union(P,Q) :- 
  234.     $check_not_function(P),
  235.     $check_not_function(Q),
  236.     $assert_cvt_buff(Q,Qclref),
  237.     $assert_cvt_dyn(P,Prref,0,0),
  238.     $arity(P,Arity1),Arity is Arity1+1,
  239.     $db_add_clref(P,Arity,Prref,1,0,Qclref).
  240.     
  241. /* This defines routines that can be used to assert facts onto the heap.
  242. */
  243.  
  244. /* We have introduced a new simulator instruction similar  to the one
  245. used to translate variables in globalset.  It is a branch
  246. instruction, called executev.  It  derefs its  argument and  if it is
  247. not a variable, does an execute to main functor symbol.  (Execute has
  248. been modified so that when a buffer is called, it branches  to disp 4
  249. in the name.)  If it  is a  variable, it  gives an  error message and
  250. fails.  */ 
  251.  
  252. /* $assert_new_t_prref(Call,Prref,Supbuff):  Call must be
  253. instantiated to a term (just used for getting psc).  If  that psc has
  254. no e.p.  then this creates a permanent buffer  containing an executev
  255. instruction, and the constant  for the  Supbuff, and  points the e.p.
  256. of Call to it.  A Prref is allocated and  the target  of the executev
  257. is set to that.  If the psc already has an e.p., the predicate fails.
  258. */ 
  259.  
  260. $assert_new_t_prref(Call,Prref,Supbuff) :-
  261.     $opcode( noop, NoopOp ),
  262.     $opcode( executev, ExecOp ),
  263.     $symtype(Call,Type),
  264.     (Type =:= 1,    /* dynamic */
  265.      $buff_code(Call,   0,  7 /*gepb*/ ,Vbuff),
  266.      $buff_code(Vbuff,  4,  6 /*gs  */ , NoopOp /*noop*/ ),
  267.      $buff_code(Vbuff,  6,  6, 0),
  268.      $buff_code(Vbuff,  8,  6, ExecOp  /* executev */ ),
  269.      $buff_code(Vbuff, 12, 18 /*ubv */ ,Prref),
  270.      $db_new_prref(Prref,2,Supbuff),
  271.      $buff_code(Vbuff, 16, 18 /*ubv */ ,Supbuff),
  272.      !
  273.     ;
  274.      $buff_code(Call,0,11,0), /* this overrides everything!! */
  275.      /* allocate new executev instruction, and supbuff ptr */
  276.      $alloc_perm(20,Vbuff), /* must make permanent */
  277.      $buff_code(Vbuff,  0, 14, Vbuff), /* set back ptr */
  278.      $buff_code(Call,   0,  9 /*pep*/ ,Vbuff),
  279.      $buff_code(Vbuff,  4,  3 /*ps */ , NoopOp /*noop*/ ),
  280.      $buff_code(Vbuff,  6,  3, 0),
  281.      $buff_code(Vbuff,  8,  3, ExecOp  /* executev */ ),
  282.      $buff_code(Vbuff, 10,  3, 0),
  283.      $buff_code(Vbuff, 12, 12 /*fv */ ,0),
  284.      $buff_code(Vbuff, 16, 12 /*fv */ ,0),
  285.      $db_new_prref(Prref,2,Supbuff),
  286.      $buff_code(Vbuff, 12, 18 /*ubv*/ ,Prref),
  287.      $buff_code(Vbuff, 16, 18 /*ubv*/ ,Supbuff)
  288.     ).
  289.  
  290.  
  291. /* $assert_alloc_t must be called first to declare that a predicate (or set
  292. of predicates) are to have facts asserted into them on the  heap.  It
  293. is given a list of Pred/Arity pairs and a size.  That  amount of heap
  294. space is reserved for facts to  be asserted  to these  predicates.  A
  295. temporary prref buffer is created.  */ 
  296.  
  297. $assert_alloc_t(Palist,Size) :- 
  298.     $alloc_heap(Size,Sbuff),
  299.     $assert_alloc_t1(Palist,Sbuff).
  300.  
  301. $assert_alloc_t1([],_).
  302. $assert_alloc_t1([F|R],Supbuff) :- 
  303.     $assert_alloc_t1(F,Supbuff),$assert_alloc_t1(R,Supbuff).
  304. $assert_alloc_t1(P/A,Supbuff) :-
  305.     $bldstr(P,A,Term),
  306.     $assert_new_t_prref(Term,Prref,Supbuff).
  307.  
  308.  
  309.  
  310. $assert_call_s(Goal) :- 
  311.     $assert_get_prref(Goal,Prref,_,_),$db_call_prref_s(Goal,Prref).
  312.  
  313.  
  314. /* $assert_get_prref(Fact,Prref,Where,Supbuff):  where Fact is a
  315. literal, which should be dynamic. The e.p. field of the main functor
  316. symbol of Fact points to either a permanent prref, or a execv buffer
  317. that points to a temporary prref. If it is a permanent prref, Where
  318. is returned as 0; if a temporary, Where is set to 2, and Supbuff is
  319. bound to the superbuffer containing the clauses. */
  320.  
  321. $assert_get_prref(Fact,Prref) :- $assert_get_prref(Fact,Prref,_,_).
  322. $assert_get_prref(Fact,Prref,Where,Supbuff) :-
  323.     $symtype(Fact,Type),
  324.     (Type =:= 1 ->    /*DYNA: must be dynamic */
  325.         $opcode( noop, NoopOp ),
  326.         $opcode( executev, ExecOp ),
  327.         $buff_code(Fact,     0,  7 /*gepb*/, Vbuff),
  328.          ($buff_code(Vbuff,  4,  6 /*gs  */, NoopOp /*noop*/ ),
  329.           $buff_code(Vbuff,  6,  6, 0),
  330.           $buff_code(Vbuff,  8,  6, ExecOp /* executev */ ),
  331.           Where=2,
  332.           $buff_code(Vbuff, 12, 18 /*ubv*/ ,Prref),
  333.           $buff_code(Vbuff, 16, 18 /*ubv*/ ,Supbuff),
  334.           !
  335.          ;
  336.           Prref=Vbuff,Where=0
  337.          )
  338.         ;
  339.          Type =\= 0, /* if undefined, just fail */
  340.          $telling(X), $tell(user),
  341.          $writename('*** Error: Illegal Predicate ref: '),
  342.          $write(Fact),$nl,
  343.          $tell(X), fail
  344.     ).
  345.  
  346. /* $assert_put_prref(Fact,Prref):  where Fact is a literal and Prref
  347. is an prref.  Prref must  be bound  to an  existing prref.   The e.p.
  348. field of the psc entry for the main functor symbol of Fact  is set to
  349. point to the Prref.  */ 
  350.  
  351. $assert_put_prref(Fact,Prref) :-
  352.     $buff_code(Fact, 0, 9 /*pep*/ ,Prref).
  353.  
  354. /* $assert_abolish_i(Fact): initializes the predicate that is the main 
  355. functor symbol of Fact to be empty, by allocating a new empty Prref and 
  356. assigning it. */
  357.  
  358. $assert_abolish_i(Fact) :- 
  359.     $db_new_prref(Prref),$assert_put_prref(Fact,Prref).
  360.